package com.yuju.common.core.service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;
import com.yuju.common.Page;
import com.yuju.common.PageModel;
import com.yuju.common.Result;
import com.yuju.common.core.dao.IBaseDao;
import com.yuju.common.util.collection.CollectionUtilss;
import com.yuju.util.GenericsUtil;

import net.sf.cglib.beans.BeanMap;

/**
 * 类名：AbstractBaseService  <br />
 *
 * 功能：抽象业务层逻辑实现
 * 泛型接口：V 表示VO，P 表示PO，PK表示该操作实体主键类型，如：Integer
 * @author : xuehj <br />
 * @Date : 2017年9月16日 下午2:58:27  <br />
 * @version : 1.1 <br />
 */
public abstract class AbstractBaseService<M, P, PK> implements IBaseService<M, P, PK> {
	private static final Logger logger = LoggerFactory.getLogger(AbstractBaseService.class);

	private Class<M> persistentClass;
	
	public abstract IBaseDao<M, P, PK> getDao();

	/**
	 * 该方法已过时，请使用PageModel list(M model, int currentPage, int rows) 方法
	 * @author 
	 */
	@Deprecated
	@Override
	public Result getPageList(M model, int currentPage, int rows) {
		logger.info("我是getPageList方法");
		Result result = new Result();
		
		// 查询会员总记录数
		Integer total = getCount(model);
		
		// 无数据时，直接返回
		if (total == 0) {
			return null;
		}
		// 设置总记录数到返回结果中
		result.setTotal(total);
		
		// List<P> list = list(model, currentPage, rows);
		
		// 转换为Model泛型List
		List<M> modelList = list(model, currentPage, rows);
		
		result.setStatus(1);
		result.setMsg("查询成功");
		
		result.setRows(modelList);
		
		return result;
	}
	
	@Override
	public PageModel pageList(M model, Integer currentPage, Integer rows) {
		logger.info("我是{}方法", "pageList");
		PageModel pageModel = getDao().list(model, currentPage, rows);
		return pageModel;
	}
	
	public int getCount(M model) {
		// 查询参数
		Map<Object, Object> map = getBeanMap(model);
		return getDao().count(map);
	}
	
	/**
	 * 功能: 查询列表实现<br/>
	 * 
	 * 重写：xuehj <br/>
	 * 
	 * @version ：1.1<br/>
	 * 
	 * @param model Model对象
	 * @param currentPage 当前页数
	 * @param rows 每页记录数
	 * @return 返回Result对象，其中包含查询数据列表，详细信息请见Result对象<br/>
	 * @see com.yuju.member.service.member.MemberService#list(com.yuju.vo.member.MemberVo)
	 */
	private List<M> list(M model, int currentPage, int rows) {
		// 查询参数
		Map<Object, Object> map = getBeanMap(model, currentPage, rows);
		
		// 查询会员列表
		List<M> list = getDao().list(map);
		
		return list;
	}
	
	@Override
	public List<M> list(M model) {
		// 查询参数
		Map<Object, Object> map = getBeanMap(model);
		
		// 查询会员列表
		// List<P> list = getDao().list(map);

		// 转换为Model泛型List
		List<M> modelList = getDao().list(map);
		return modelList;
	}

	/**
	 * 功能:保存对象 <br/>
	 * 
	 * 重写：xuehj <br/>
	 * 
	 * @Date ：2017年9月16日 下午2:59:47<br/>
	 * 
	 * @param model Model对象
	 * @return <br/>
	 * @see com.yuju.owner.hourse.service.base.BaseService#saveObj(java.lang.Object)
	 */
	@Override
	public int save(M model) {
		// 保存数据
		int rows = getDao().saveSelective(model);
		return rows;
	}

	/**
	 * 功能: 更新对象<br/>
	 * 
	 * 重写：xuehj <br/>
	 * 
	 * @Date ：2017年9月16日 下午3:00:14<br/>
	 * 
	 * @param model Model对象
	 * @return <br/>
	 * @see com.yuju.member.service.common.BaseService#updateObj(java.lang.Object)
	 */
	@Override
	public int update(M model) {
		// 更新数据
		return getDao().update(model);
	}

	/**
	 * 功能: 更新对象<br/>
	 * 
	 * 重写：xuehj <br/>
	 * 
	 * @Date ：2017年9月16日 下午3:00:14<br/>
	 * 
	 * @param model Model对象
	 * @return <br/>
	 * @see com.yuju.member.service.common.BaseService#updateObj(java.lang.Object)
	 */
	@Override
	public int updateSelective(M model) {
		// 更新数据
		return getDao().updateSelective(model);
	}

	/**
	 * 功能: 删除对象<br/>
	 * 
	 * 重写：xuehj <br/>
	 * 
	 * @Date ：2017年9月16日 下午3:01:01<br/>
	 * 
	 * @param id 主键ID
	 * @return <br/>
	 * @see com.yuju.member.service.common.BaseService#delObj(java.lang.Object)
	 */
	@Override
	public int del(PK id) {
		// 删除数据
		return getDao().del(id);
	}

	/**
	 * 
	 * 功能: 查找对象<br/>
	 * 
	 * 重写：xuehj <br/>
	 * 
	 * @Date ：2017年9月16日 下午3:01:23<br/>
	 * 
	 * @param model Model对象
	 * @return <br/>
	 * @see com.yuju.member.service.common.BaseService#findObj(java.lang.Object)
	 */
	@Override
	public M find(M model) {
		// 查询参数
		Map<Object, Object> map = getBeanMap(model);
		
		if (map != null && map.isEmpty()) {
			return null;
		}
		
		// 查询会员列表
		List<M> list = getDao().list(map);
		
		if (list != null && !list.isEmpty()) {
			return list.get(0);
		}
		
		return null;
	}
	
	@Override
	public M findById(PK id) {
		P p = getDao().getObj(id);
		if (p != null) {
			return convert(p);
		}
		return null;
	}

	/**
	 * 功能：将bean转换成Map<br/>
	 * 构造分页对象
	 * @author xuehj
	 * @Date 2017年9月13日 下午6:46:20 <br/>
	 */
	public Map<Object, Object> getBeanMap(M model, int currentPage, int rows) {
		Map<Object, Object> map = getBeanMap(model);

		if (rows > 0) {
			Page page = new Page(rows, currentPage);
			map.put("page", page);
		}
		
	    return map;
	}
	
	/**
	 * 功能：将bean转换成Map<br/>
	 *
	 * @author xuehj
	 * @Date 2017年9月13日 下午6:46:20 <br/>
	 */
	public Map<Object, Object> getBeanMap(M model) {
		Map<Object, Object> map = Maps.newHashMap();
	    if (model != null) {
	        BeanMap beanMap = BeanMap.create(model);
	        for (Object key : beanMap.keySet()) {
	        	if (null != beanMap.get(key)) {
	        		map.put(key, beanMap.get(key));
	        	}
	        }
	    }
	    return map;
	}
	
	/**
	 * 功能：VO转换PO<br/>
	 * @param from VO对象
	 * @param clazz PO类型对象
	 * @author xuehj
	 * @Date 2017年9月16日 下午12:02:15 <br/>
	 */
	public M convert(P from, Class<M> clazz) {
		if (from == null) {
			return null;
		}
		M to = null;
		try {
			to = clazz.newInstance();
		} catch (Exception e) {
			logger.error("初始化{}对象失败。", clazz, e);
		}
		convert(from, to);
		
		return to;
	}
	
	public List<M> convert(List<P> fromList) {
		if (CollectionUtilss.isEmpty(fromList)) {
            return null;
        }
		this.persistentClass = (Class<M>)GenericsUtil.getSuperClassGenricType(this.getClass(), 0);
		return convert(fromList, this.persistentClass);
	}
	
	/**
     * 批量对象转换
     */
    public List<M> convert(List<P> fromList, Class<M> clazz) {
        if (CollectionUtilss.isEmpty(fromList)) {
            return null;
        }
        List<M> toList = new ArrayList<M>();
        for (P from : fromList) {
            toList.add(convert(from, clazz));
        }
        return toList;
    }
	
	/**
	 * 功能：属性拷贝<br/>
	 * @param from PO对象
	 * @param to Model对象
	 * @author xuehj
	 * @Date 2017年9月16日 下午12:01:02 <br/>
	 */
	protected void convert(P from, M to) {
//		BeanMappingUtil.copy(from, to);
		try {
			BeanUtils.copyProperties(to, from);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 功能：VO转换成PO<br/>
	 * @param from VO对象
	 * @author xuehj
	 * @Date 2017年9月16日 下午12:00:41 <br/>
	 */
	public M convert(P from) {
		this.persistentClass = (Class<M>)GenericsUtil.getSuperClassGenricType(this.getClass(), 0);
		return convert(from, this.persistentClass);
	}
}
